Passed
Branchmaster (b3b9b8)
by Plamen
01:30
created

table.singleton.js ➔ ... ➔ this.checkSkip   A

Complexity

Conditions 4
Paths 3

Size

Total Lines 11
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 4
eloc 8
c 1
b 0
f 0
nc 3
nop 1
dl 0
loc 11
rs 10
1
// https://addyosmani.com/resources/essentialjsdesignpatterns/book/#singletonpatternjavascript
2
var strAsc = String.fromCharCode(9650); //▲
3
var strDesc = String.fromCharCode(9660);//▼ 
4
var TableSingleton = (function(){
5
    // Instance stores a reference to the Singleton
6
    var instance;
7
    function initInstance(){
8
        // Singleton
9
        // Private methods and variables
10
        function getParent(obj, objType){
11
            while(obj && obj.tagName !== objType.toUpperCase()){
12
                obj = obj.parentNode;
13
            }
14
            return obj;
15
        }
16
        function BuildRequest(request, crntTableId, skipPropertyArray){
17
            this.rq = request;
18
            this.checkSkip = function(skipProperty){
19
                var result = false;
20
                if(skipPropertyArray && Object.prototype.toString
21
                        .call(skipPropertyArray) === '[object Array]'
22
                        ){
23
                    if(skipPropertyArray.indexOf(skipProperty) >= 0){
24
                        result = true;
25
                    }
26
                }
27
                return result;
28
            };
29
            this.getSort = function(){
30
                var thTags = document.getElementById(crntTableId)
31
                        .getElementsByTagName("thead")[0]
32
                        .getElementsByTagName("th");
33
                var length = thTags.length;
34
                for(var i = 0; i < length; i++){
35
                    var link = thTags[i].getElementsByTagName("a")[0];
36
                    if(link){
37
                        var span = link.getElementsByTagName("span")[0];
38
                        if(span && this.setSortByFirstLinkFirstSpan(span, i)){
39
                            break;
40
                        }
41
                    }
42
                }
43
            };
44
            this.setSortByFirstLinkFirstSpan = function(span, i){
45
                var order = span.innerHTML;
46
                if(order.length === 1){
47
                    rq.colNo = i;
0 ignored issues
show
Bug introduced by
The variable rq seems to be never declared. If this is a global, consider adding a /** global: rq */ comment.

This checks looks for references to variables that have not been declared. This is most likey a typographical error or a variable has been renamed.

To learn more about declaring variables in Javascript, see the MDN.

Loading history...
48
                    rq.colOrd = (order === window.strDesc) ?
49
                            "desc" : "asc";
50
                }
51
                return this.rq.colNo === i;
52
            };
53
            this.getFilter = function(){
54
                var r = getFilterFieldsByTableID(crntTableId);
55
                if(r.filter !== null){
56
                    this.rq.filter = r.filter;
57
                }
58
                if(r.filterBy !== null){
59
                    this.rq.filterBy = r.filterBy;
60
                }
61
            };
62
63
            /* Build request object */
64
            if(!this.checkSkip("sort")){
65
                this.getSort();
66
            }
67
            if(!this.checkSkip("filter")){
68
                this.getFilter();
69
            }
70
71
            this.rq.tableId = crntTableId;
72
            return this.rq;
73
        }
74
        function getFilterFieldsByTableID(tableID){
75
            var fields = {filterBy: null, filter: null};
76
            var filterDiv = getFilterDivByTableIDOrNull(tableID);
77
            if(filterDiv !== null){
78
                setFilterFields(fields, filterDiv);
79
            }
80
            return fields;
81
        }
82
        function getFilterDivByTableIDOrNull(tableID){
83
            var res = null;
84
            if(document.getElementById(tableID).parentNode.getElementsByTagName("div").length > 0){
85
                for(var i = 0; i < document.getElementById(tableID).parentNode.getElementsByTagName("div").length; i++){
86
                    if(document.getElementById(tableID).parentNode.getElementsByTagName("div")[i].getAttribute("class") === "filter"){
87
                        return document.getElementById(tableID).parentNode.getElementsByTagName("div")[i];
88
                    }
89
                }
90
91
            }
92
            return res;
93
        }
94
        function setFilterFields(fields, filterDiv){
95
            var slctObj = filterDiv.getElementsByTagName("select")[0];
96
            if(slctObj && slctObj.options[slctObj.selectedIndex].value !== "all"){
97
                fields.filterBy = slctObj.options[slctObj.selectedIndex].value;
98
            }
99
            var textObj = filterDiv.getElementsByTagName("input")[0];
100
            if(textObj && textObj.value && textObj.value.length !== 0){
101
                fields.filter = encodeURIComponent(textObj.value.trim());
102
            }
103
        }
104
        function FilterGetTableId(field){
105
            if(field.tagName.toLowerCase() !== "select"){
106
                return field.getAttribute("data-table-id");
107
            }
108
            var f = field.parentNode.parentNode.getElementsByTagName("input")[0];
109
            return '' === f.value ? null : f.getAttribute("data-table-id");
110
        }
111
        var tail = [];
112
        function LoadData(tableContainer, rq){
113
            instance.setVisability(tableContainer, false);
114
            if(window.XMLHttpRequest){
115
                xmlhttp = new XMLHttpRequest();/* code for IE7+, Firefox, Chrome, Opera, Safari */
0 ignored issues
show
Bug introduced by
The variable xmlhttp seems to be never declared. Assigning variables without defining them first makes them global. If this was intended, consider making it explicit like using window.xmlhttp.
Loading history...
116
            }else{ 
117
                xmlhttp = new window.ActiveXObject("Microsoft.XMLHTTP");/*code for IE6, IE5 */
118
            }
119
            for(var i = 0; i < tail.length; i++){
120
                var ex_xmlhttp = tail.shift();
121
                ex_xmlhttp.abort();
122
            }
123
            xmlhttp.onreadystatechange = function(){
124
                if(xmlhttp.readyState === 4 && xmlhttp.status === 200){
125
                    d = JSON.parse(xmlhttp.responseText);
0 ignored issues
show
Bug introduced by
The variable d seems to be never declared. Assigning variables without defining them first makes them global. If this was intended, consider making it explicit like using window.d.
Loading history...
126
                    table.DrawSection(tableContainer, d.body);
127
                    table.DrawSection(tableContainer, d.footer, "tfoot");
128
                    table.LoadEndCalback(tableContainer);
129
                    table.setVisability(tableContainer, true);
130
                    if(typeof rq === "object"){
131
                        var hover = document.getElementById(rq.tableId)
132
                                    .getElementsByTagName("th")[rq.colNo].lang;
133
                        if(hover){
134
                            table.ColumnHover(tableContainer, rq.colNo);
135
                        }
136
                    }
137
                }
138
            };
139
            xmlhttp.open("GET", RequestToUrl(rq), true);
140
            xmlhttp.send();
141
            tail.push(xmlhttp); //put at tail to can abort later any previous
142
        }
143
        function RequestToUrl(rq){
144
            var url = location.pathname + ".json" + location.search;
145 View Code Duplication
            if(typeof rq === "object"){
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
146
                var getUrlVarName = {
147
                    colNo: "col", colOrd: "ord", filter: "filter",
148
                    filterBy: "filter-by", pageNo: "pg", exportType: "export",
149
                    tableId: "table-id"
150
                };
151
                var flagFirst = location.search.length < 1 ? true : false;
152
                for(var r in rq){
1 ignored issue
show
Complexity introduced by
A for in loop automatically includes the property of any prototype object, consider checking the key using hasOwnProperty.

When iterating over the keys of an object, this includes not only the keys of the object, but also keys contained in the prototype of that object. It is generally a best practice to check for these keys specifically:

var someObject;
for (var key in someObject) {
    if ( ! someObject.hasOwnProperty(key)) {
        continue; // Skip keys from the prototype.
    }

    doSomethingWith(key);
}
Loading history...
153
                    var clue = flagFirst === true ? "?" : "&";
154
                    url += clue + getUrlVarName[r] + "=" + rq[r];
155
                    flagFirst = false;
156
                }
157
            }
158
            return url;
159
        }
160
        function columnHoverRelease(rows, upto){
161
            for(var i = 0; i < upto; i++){
162
                for(var j = 0; j < rows[i].cells.length; j++){
163
                    if(rows[i].cells[j].lang){
164
                        rows[i].cells[j].removeAttribute("lang");
165
                    }
166
                }
167
            }
168
        }
169
        function clearSection(tSection){
170
            if(iePrior(9)){
171
                if(tSection.firstChild){
172
                    while(tSection.firstChild){
173
                        tSection.removeChild(tSection.firstChild);
174
                    }
175
                }
176
            }else{
177
                tSection.innerHTML = "";
178
            }
179
        }
180
        function iePrior(v){
181
            var rv = false;
182
            if(window.navigator.appName === 'Microsoft Internet Explorer'){
183
                var ua = window.navigator.userAgent;
184
                var re = new RegExp("MSIE ([0-9]{1,}[\.0-9]{0,})");
185
                if(re.exec(ua) !== null){
186
                    rv = parseFloat(RegExp.$1);
187
                }
188
                rv = rv < v ? true : false;
189
            }
190
            return rv;
191
        }
192
        function setPagingLinksSetActions(tContainer){
193
            var pLinks = tContainer.querySelectorAll("tfoot .paging a");
194
            if(pLinks.length > 0){
195
                for(var j = 0; j < pLinks.length; j++){
196
                    pLinks[j].setAttribute("href", "javascript:void(0);");
197
                    pLinks[j].setAttribute("onclick", "return table.GoPage(this);");
198
                }
199
            }
200
        }
201
        function footerProcessPaginationLinks(tSection){
202
            var pLinks = tSection.querySelectorAll(".paging a");
203
            if(pLinks.length > 0){
204
                for(var j = 0; j < pLinks.length; j++){
205
                    pLinks[j].setAttribute("href", "javascript:void(0);");
206
                    pLinks[j].setAttribute("onclick", "return table.GoPage(this);");
207
                }
208
            }
209
        }
210
        function SetTheTableColumnsHoverEffect(tableContainer){
211
            if(iePrior(9)){
212
                return;
213
            }
214
            var tContainer = document.getElementById(tableContainer);
215
            var tHcells = tContainer.rows[0].cells;
216
            for(var i = 0; i < tHcells.length; i++){
217
                if(tHcells[i].firstChild.tagName === "A"){
218
                    tHcells[i].firstChild.setAttribute("onmouseover", "table.ColumnHover('" + tableContainer + "'," + i + ");");
219
                    tHcells[i].firstChild.setAttribute("onmouseout", "table.ColumnHover('" + tableContainer + "');");
220
                }
221
            }
222
            setPagingLinksSetActions(tContainer);
223
        }
224
        
225
        return {
226
            // Public methods and variables
227
            /*publicProperty: "I am public",
228
            publicMethod: function(){
229
                console.log("The public also can see me!");
230
            },
231
            getRandomNumber: function(){
232
                return privateRandomNumber;
233
            }*/
234
            // - - - Imported start - - -
235
            rq: null,
236
            ReloadData: function(tableId){
237
                var request = {};
238
                BuildRequest(request, tableId);
239
                LoadData(tableId, request);
240
            },
241
            Filter: function(field){
242
                var crntTableId = FilterGetTableId(field);
243
                if(crntTableId !== null){
244
                    var request = {};
245
                    var exRq = this.rq;
246
                    BuildRequest(request, crntTableId);
247
                    if(exRq === null ||
248
                        request.filter !== exRq.filter ||
249
                        request.filterBy !== exRq.filterBy
250
                    ){
251
                        LoadData(crntTableId, request);
252
                    }
253
                }
254
            },
255 View Code Duplication
            GoPage: function(lnk){
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
256
                var request = {};
257
                var table = getParent(lnk, "table");
258
                var crntTableId = table.getAttribute("id");
259
                BuildRequest(request, crntTableId);
260
                //check & serve pagination jump links
261
                var jumpDir = lnk.innerHTML.trim().substr(0, 1);
262
                if(jumpDir === "+" || jumpDir === "-"){
263
                    var current = table.querySelector("tfoot .paging .a").innerHTML;
264
                    var jump = lnk.innerHTML.replace("K", "000").replace("M", "000000000");
265
                    var jumpPage = (parseInt(current) + parseInt(jump));
266
                    lnk.parentNode.setAttribute("data-page", jumpPage);
267
                    lnk.style.transform = "none";
268
                }
269
                request.pageNo = lnk.parentNode.hasAttribute("data-page") ?
270
                                    lnk.parentNode.getAttribute("data-page") :
271
                                    lnk.innerHTML;
272
                LoadData(crntTableId, request);
273
                return false;
274
            },
275
            Export: function(lnk, eType){
276
                var request = {};
277
                var crntTableId = getParent(lnk, "table").getAttribute("id");
278
                BuildRequest(request, crntTableId);
279
                request.exportType = ["CSV", "Excel"].indexOf(eType) >= 0 ?
280
                                        eType : 
281
                                        "csv";
282
                window.open(RequestToUrl(request));
283
                return false;
284
            },
285 View Code Duplication
            Sort: function(colNo, lnk){
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
286
                var request = {};
287
                var crntTableId = getParent(lnk, "table").getAttribute("id");
288
                BuildRequest(request, crntTableId);
289
                if(Math.round(colNo) === request.colNo){
290
                    request.colOrd = request.colOrd === "asc" ? "desc" : "asc";
291
                }else{
292
                    request.colNo = Math.round(colNo);
293
                    request.colOrd = "asc";
294
                }
295
                LoadData(crntTableId, request);
296
                /* Clear and add new sort arrow */
297
                var headSpans = getParent(lnk, "thead").getElementsByTagName("span");
298
                var length = headSpans.length;
299
                for(var i = 0; i < length; i++){
300
                    headSpans[i].innerHTML = "";
301
                }
302
                lnk.getElementsByTagName("span")[0].innerHTML = (request.colOrd === "desc" ? window.strDesc : window.strAsc);
303
            },
304
            DrawSection: function(tableContainer, dt, tSection){
305
                var section = tSection === "tfoot" ? "tfoot" : "tbody";
306
                tSection = document.getElementById(tableContainer).
307
                            getElementsByTagName(section)[0];
308
                clearSection(tSection);
309
                for(var i = 0; i < dt.length; i++){
310
                    var row = dt[i];
311
                    var tRow = document.createElement("tr");
312
313
                    this.DrawRow(row, tRow);
314
315
                    tSection.appendChild(tRow);
316
                    if(section === "tfoot"){
317
                        footerProcessPaginationLinks(tSection);
318
                    }
319
                    this.AppendRowCalback(tableContainer);
320
                }
321
            },
322
            DrawRow: function(row, tRow){
323
                for(var cell in row){
1 ignored issue
show
Complexity introduced by
A for in loop automatically includes the property of any prototype object, consider checking the key using hasOwnProperty.

When iterating over the keys of an object, this includes not only the keys of the object, but also keys contained in the prototype of that object. It is generally a best practice to check for these keys specifically:

var someObject;
for (var key in someObject) {
    if ( ! someObject.hasOwnProperty(key)) {
        continue; // Skip keys from the prototype.
    }

    doSomethingWith(key);
}
Loading history...
324
                    var tCell = document.createElement("td");
325
                    if(typeof row[cell] === "string" || typeof row[cell] === "number"){
326
                        tCell.innerHTML = row[cell];
327
                    }else if(typeof row[cell] === "object"){
328
                        this.DrawCellFromObject(row, cell, tCell);
329
                    }
330
                    tRow.appendChild(tCell);
331
                }
332
            },
333
            DrawCellFromObject: function(row, cell, tCell){
334
                for(var attr in row[cell]){
1 ignored issue
show
Complexity introduced by
A for in loop automatically includes the property of any prototype object, consider checking the key using hasOwnProperty.

When iterating over the keys of an object, this includes not only the keys of the object, but also keys contained in the prototype of that object. It is generally a best practice to check for these keys specifically:

var someObject;
for (var key in someObject) {
    if ( ! someObject.hasOwnProperty(key)) {
        continue; // Skip keys from the prototype.
    }

    doSomethingWith(key);
}
Loading history...
335
                    if(typeof row[cell][attr] === "string"){
336
                        tCell.innerHTML = row[cell][attr];
337
                    }else if(typeof row[cell][attr] === "object"){
338
                        for(var v in row[cell][attr]){
1 ignored issue
show
Complexity introduced by
A for in loop automatically includes the property of any prototype object, consider checking the key using hasOwnProperty.

When iterating over the keys of an object, this includes not only the keys of the object, but also keys contained in the prototype of that object. It is generally a best practice to check for these keys specifically:

var someObject;
for (var key in someObject) {
    if ( ! someObject.hasOwnProperty(key)) {
        continue; // Skip keys from the prototype.
    }

    doSomethingWith(key);
}
Loading history...
339
                            tCell.setAttribute(v, row[cell][attr][v]);
340
                        }
341
                    }
342
                }
343
            },
344
            ColumnHover: function(tableContainer, index){
345
                if(!iePrior(9)){
346
                    var rows = document.getElementById(tableContainer).rows;
347
                    var upto = rows.length - 1;
348
                    if(typeof index === "undefined"){
349
                        columnHoverRelease(rows, upto);
350
                    } else {
351
                        for(var i = 0; i < upto; i++){
352
                            rows[i].cells[index].setAttribute("lang", "col-hover");
353
                        }
354
                    }
355
                }
356
            },
357
            setVisability: function(tableContainer, rq){
358
                var tbl = document.getElementById(tableContainer);
359
                if(rq === true){
360
                    tbl.style.filter = "none";
361
                    tbl.style.opacity = "1";
362
                    tbl.style.cursor = "auto";
363
                }else if(rq === false){
364
                    tbl.style.filter = "blur(1px)";
365
                    tbl.style.opacity = "0.8";
366
                    tbl.style.cursor = "wait";
367
                }else{
368
                    console.error("table error in the rq value");
369
                }
370
            },
371
            init: function(tableId){
372
                SetTheTableColumnsHoverEffect(tableId);
373
            },
374
            loadJS: function(src){
375
                var s = document.createElement('script');
376
                s.src = src;
377
                document.getElementsByTagName('head')[0].appendChild(s);
378
            },
379
            loadCSS: function(src){
380
                var s = document.createElement('link');
381
                s.href = src;
382
                s.rel = "stylesheet";
383
                document.getElementsByTagName('head')[0].appendChild(s);
384
            },
385
            LoadEndCalback: function(tableId){
386
                if(tableId){/*Allows override*/
0 ignored issues
show
Comprehensibility Documentation Best Practice introduced by
This code block is empty. Consider removing it or adding a comment to explain.
Loading history...
387
                }
388
            },
389
            AppendRowCalback: function(tableId){
390
                if(tableId){/*Allows override*/
0 ignored issues
show
Comprehensibility Documentation Best Practice introduced by
This code block is empty. Consider removing it or adding a comment to explain.
Loading history...
391
                }
392
            }
393
            // - - - Imported end - - -
394
        };
395
    }
396
    return {
397
        //Get the Singleton instance if one exists, or create one if it doesn't
398
        getInstance: function(){
399
            if(!instance){
400
                instance = initInstance();
401
            }
402
            return instance;
403
        }
404
    };
405
})();
406
var table = TableSingleton.getInstance();
407